﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="Series.cs" company="">
//   
// </copyright>
// <summary>
//   The series.
// </summary>
// --------------------------------------------------------------------------------------------------------------------


using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

namespace Systemathics.FrameWork
{
    [Serializable]
    public class Series<T> : EventArgs, IEnumerable<T>, ICloneable where T : ICloneable
    {
        public Guid Id { get; set; }
        public string Ticker { get; set; }
        protected List<T> series;
        protected event EventHandler<FireMessageEventArgs> EmitBaseSeriesError;

        #region Constructors

        public Series(string name)
        {
            Ticker = name;
            series = new List<T>();
        }
        public Series(Guid id)
        {
            Id = id;
            series = new List<T>();
        }
        public Series(string name, List<T> t)
        {
            Ticker = name;
            series = t;
        }
        public Series(Guid id, List<T> t)
        {
            Id = id;
            series = t;
        }

        #endregion Constructors

        #region IEnumerable<T> Members

        public IEnumerator<T> GetEnumerator()
        {
            for (int j = 0; j < series.Count; j++)
                yield return series.ElementAt(j);
        }


        IEnumerator IEnumerable.GetEnumerator()
        {
            for (int j = 0; j < series.Count; j++)
                yield return series.ElementAt(j);
        }

        #endregion

        #region Series Methods

        public T this[int index]
        {
            get
            {
                try
                {
                    lock (this)
                    {
                        return series.ElementAt(index);
                    }
                }
                catch (Exception ex)
                {
                    if (EmitBaseSeriesError != null)
                        EmitBaseSeriesError(this, new FireMessageEventArgs(ex, Time.Now.TimeOfDay));
                }
                return default(T);
            }
        }
        public int Count
        {
            get
            {
                try
                {
                    lock (this)
                    {
                        return series.Count;
                    }
                }
                catch (Exception ex)
                {
                    if (EmitBaseSeriesError != null)
                        EmitBaseSeriesError(this, new FireMessageEventArgs(ex, Time.Now.TimeOfDay));
                }
                return 0;
            }
        }
        public void Add(T t)
        {
            try
            {
                lock (this)
                {
                    series.Add(t);
                }
            }
            catch (Exception ex)
            {
                if (EmitBaseSeriesError != null)
                    EmitBaseSeriesError(this, new FireMessageEventArgs(ex, Time.Now.TimeOfDay));
            }
        }
        public bool Contains(T t)
        {
            lock (this)
            {
                return series.Contains(t);
            }
        }
        public T Ago(int n)
        {
            try
            {
                lock (this)
                {
                    return series.ElementAt(series.Count - n - 1);
                }
            }
            catch (Exception ex)
            {
                if (EmitBaseSeriesError != null)
                    EmitBaseSeriesError(this, new FireMessageEventArgs(ex, Time.Now.TimeOfDay));
            }
            return default(T);
        }
        public T First()
        {
            try
            {
                lock (this)
                {
                    return series.First();
                }
            }
            catch (Exception ex)
            {
                if (EmitBaseSeriesError != null)
                    EmitBaseSeriesError(this, new FireMessageEventArgs(ex, Time.Now.TimeOfDay));
            }
            return default(T);
        }
        public T Last()
        {
            try
            {
                lock (this)
                {
                    return series.Last();
                }
            }
            catch (Exception ex)
            {
                if (EmitBaseSeriesError != null)
                    EmitBaseSeriesError(this, new FireMessageEventArgs(ex, Time.Now.TimeOfDay));
            }
            return default(T);
        }
        public void Remove(int index)
        {
            try
            {
                lock (this)
                {
                    series.RemoveAt(index);
                }
            }
            catch (Exception ex)
            {
                if (EmitBaseSeriesError != null)
                    EmitBaseSeriesError(this, new FireMessageEventArgs(ex, Time.Now.TimeOfDay));
            }
        }
        public void Clear()
        {
            try
            {
                lock (this)
                {
                    series.Clear();
                }
            }
            catch (Exception ex)
            {
                if (EmitBaseSeriesError != null)
                    EmitBaseSeriesError(this, new FireMessageEventArgs(ex, Time.Now.TimeOfDay));
            }
        }

        #endregion Series Methods 

        #region ICloneable Members

        public object Clone()
        {
            return (T)MemberwiseClone();
        }

        #endregion
    }
} 